package br.com.fieo.sgee.logic;

import br.com.fieo.sgee.dao.DaoFactory;
import br.com.fieo.sgee.exception.UserNotFoundException;
import br.com.fieo.sgee.exception.ValidFieldException;
import br.com.fieo.sgee.model.User;
import java.util.HashMap;
import java.util.Map;

/**
 * Classe que controla a lógica de négocio da entidade usuário
 * @author rbueno
 */
public class UserLogic {

    /** instancia da classe UserLogic */
    private static UserLogic _instance = null;
    /** instancia da classe DaoFactory */
    private final DaoFactory factory;
    /** Usuário logado no sistema */
    private User user;

    /**
     * Construtor privado para aplicar o Singleton
     */
    private UserLogic() {
        this.factory = new DaoFactory();
    }

    /**
     * Singleton para impedir que criemos mais de uma DaoFactory
     * @return instancia da classe
     */
    static public UserLogic getInstance() {
        if (_instance == null) {
            _instance = new UserLogic();
        }
        return _instance;
    }

    /**
     * Método para efetuar o login do usuário no sistema
     * @param login para identificar o usuário
     * @param password de segurança
     * @throws ValidFieldException Caso algum campo esteja inválido, ou o usuário não esteje correto.
     * @throws UserNotFoundException Caso o usuário não sejá encontrado
     */
    public void login(String login, char[] password) throws ValidFieldException, UserNotFoundException {

        final Map<String, String> messages = new HashMap<String, String>();

        try {

            if (login.length() == 0) {
                messages.put("login", ValidFieldException.FIELD_NOT_EMPTY_M);
            }

            if (login.length() > 20) {
                messages.put("login", ValidFieldException.FIELD_MAXIMUM_SIZE(20));
            }

            if (password.length == 0) {
                messages.put("senha", ValidFieldException.FIELD_NOT_EMPTY_F);
            }

            if (password.length > 40) {
                messages.put("senha", ValidFieldException.FIELD_MAXIMUM_SIZE(40));
            }

            if (!messages.isEmpty()) {
                throw new ValidFieldException(messages);
            }

            this.user = factory.getUsuarioDao().login(login, password);

            if (this.user == null) {
                throw new UserNotFoundException(UserNotFoundException.LOGIN_FAIL);
            }

        } catch (ValidFieldException ex) {
            factory.rollback();
            throw ex;
        } catch (UserNotFoundException ex) {
            factory.rollback();
            throw ex;
        }

    }

    /**
     * Validar o usuário antes de salvar na base de dados.
     * @param u Usuário preenchido
     */
    public void save(User u) {

        factory.beginTransaction();
        factory.getUsuarioDao().save(u);
        factory.commit();
        factory.close();

    }

    /**
     * Modificar o password do usuário atual
     * @param password Nova senha
     * @param password_confirmation Confirmação para a nova senha
     * @throws ValidFieldException Caso algum campo preenchido sejá inválido
     */
    public void changePassword(char[] password, char[] password_confirmation) throws ValidFieldException {

        final Map<String, String> messages = new HashMap<String, String>();

        try {

            if (password.length < 6) {
                messages.put("senha", ValidFieldException.FIELD_MINIMUM_SIZE(6));
            }

            if (password.length > 40) {
                messages.put("senha", ValidFieldException.FIELD_MAXIMUM_SIZE(40));
            }

            if (password_confirmation.length < 6) {
                messages.put("confirmação", ValidFieldException.FIELD_MINIMUM_SIZE(6));
            }

            if (password_confirmation.length > 40) {
                messages.put("confirmação", ValidFieldException.FIELD_MAXIMUM_SIZE(40));
            }

            if (!new String(password).equals(new String(password_confirmation))) {
                messages.put("senha", ValidFieldException.CONFIRMATION_INVALID);
            }

            if (!messages.isEmpty()) {
                throw new ValidFieldException(messages);
            }

            this.user.setPassword(password);
            factory.beginTransaction();
            factory.getUsuarioDao().merge(this.user);
            factory.commit();

        } catch (ValidFieldException e) {
            factory.rollback();
            throw e;
        }

    }

    /**
     * Obter o usuário logado no sistema
     * @return Usuário logado
     */
    public User getUser() {
        return user;
    }
}
